package com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.SmsAssetFixedStorage;
import com.xyht.sca_s.student_manage_system.modules.asset.mapper.SmsAssetFixedStorageMapper;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.SmsAssetSelfInspection;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.SmsAssetSelfInspectionDetail;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.SmsAssetSelfInspectionPlan;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.req.SmsAssetSelfInspectionPlanReq;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.resp.SmsAssetSelfInspectionOrgResp;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.resp.SmsAssetSelfInspectionPlanResp;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.mapper.SmsAssetSelfInspectionDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.mapper.SmsAssetSelfInspectionMapper;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.mapper.SmsAssetSelfInspectionPlanMapper;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.service.SmsAssetSelfInspectionPlanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.*;
import com.xyht.sca_s.student_manage_system.modules.newTips.util.NewTipsUtil;
import com.xyht.sca_s.student_manage_system.modules.org.entity.OrgNode;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgStructure;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgUserRelation;
import com.xyht.sca_s.student_manage_system.modules.org.mapper.SmsOrgStructureMapper;
import com.xyht.sca_s.student_manage_system.modules.org.mapper.SmsOrgUserRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.org.util.NodeUtil;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.entity.resp.SmsSearchUserResp;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.util.*;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.asset.constant.AssetStatusConstant.ASSET_STATUS_OUT;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.constant.AssetStatusConstant.ASSET_STATUS_UNKNOWN;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.constant.IsCompletedConstant.COMPLETED_TYPE_YES;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.constant.IsUseConstant.IS_USE_NO;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.constant.IsUseConstant.IS_USE_YES;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.constant.PlanRangeConstant.PLAN_RANGE_TYPE_DEPARTMENT;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.constant.PlanRangeConstant.PLAN_RANGE_TYPE_PERSONAL;

/**
 * <p>
 * 资产自查计划表 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2024-09-28
 */
@Service
public class SmsAssetSelfInspectionPlanServiceImpl extends ServiceImpl<SmsAssetSelfInspectionPlanMapper, SmsAssetSelfInspectionPlan> implements SmsAssetSelfInspectionPlanService {

    @Resource
    private SmsAssetSelfInspectionPlanMapper selfInspectionPlanMapper;
    @Resource
    private SmsAssetSelfInspectionMapper smsAssetSelfInspectionMapper;
    @Resource
    private SmsAssetSelfInspectionDetailMapper smsAssetSelfInspectionDetailMapper;
    @Resource
    private SmsUserMapper smsUserMapper;
    @Resource
    private SmsOrgStructureMapper smsOrgStructureMapper;
    @Resource
    private SmsOrgUserRelationMapper smsOrgUserRelationMapper;
    @Resource
    private SmsAssetFixedStorageMapper smsAssetFixedStorageMapper;
    @Resource
    private NewTipsUtil newTipsUtil;

    @Override
    @Transactional
    public ResponseResult addPlan(SmsAssetSelfInspectionPlanReq planReq, String userId) {
        // 参数校验
        if (isNullOrEmpty(planReq.getPlanName(), planReq.getBgTime(), planReq.getEndTime(), planReq.getPlanRangeType(),
                planReq.getRangeIdList()) || planReq.getRangeIdList().size() < 1) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        if (planReq.getBgTime().compareTo(planReq.getEndTime()) > 0) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_TIME_ILLEGALITY);
        }
        List<String> userIdList = new ArrayList<>();
        //部门
        if (planReq.getPlanRangeType() == PLAN_RANGE_TYPE_DEPARTMENT ) {
            List<SmsOrgStructure> orgStructureList = smsOrgStructureMapper.selectBatchIds(planReq.getRangeIdList());
            if (orgStructureList == null || orgStructureList.isEmpty()) {
                return CommonResult.failed(CommonCodeEnum.ORGANIZATION_NOT_EXIST);
            }
            List<String> orgLevelList = orgStructureList.stream().map(SmsOrgStructure::getLevel).distinct().collect(Collectors.toList());
            List<String> count = orgLevelList
                    .stream()
                    .filter(i -> !orgLevelList.contains("1"))
                    .collect(Collectors.toList());
            if (!count.isEmpty()) {
                return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_DEPARTMENT_EXIST);
            }
            for (String orgId : planReq.getRangeIdList()) {
                SmsOrgStructure orgStructure = smsOrgStructureMapper.selectById(orgId);
                if (orgStructure == null) {
                    return CommonResult.failed(CommonCodeEnum.ORG_NOT_EXIST);
                }
                //获取组织下的所有用户
                List<SmsOrgStructure> list = smsOrgStructureMapper.selectList(null);
                List<OrgNode> orgNodes = new ArrayList<>();
                for (SmsOrgStructure smsOrgStructure : list) {
                    OrgNode orgNode = new OrgNode();
                    BeanUtils.copyProperties(smsOrgStructure, orgNode);
                    orgNodes.add(orgNode);
                }
                List<Integer> list1 = NodeUtil.getChildNodes(orgNodes, Integer.parseInt(orgId));
                List<String> userIdAllList = smsOrgUserRelationMapper.selectList(new LambdaQueryWrapper<SmsOrgUserRelation>()
                                .in(SmsOrgUserRelation::getOrgId, list1))
                        .stream()
                        .map(SmsOrgUserRelation::getUserId)
                        .collect(Collectors.toList());
                if (!userIdAllList.isEmpty()) {
                    List<String> userIdListFilter = smsUserMapper.selectBatchIds(userIdAllList)
                            .stream()
                            .filter(i -> i.getFlag() == 0)
                            .map(SmsUser::getId)
                            .collect(Collectors.toList());
                    userIdList.addAll(userIdListFilter);
                }

            }
            //个人
        } else if (planReq.getPlanRangeType() == PLAN_RANGE_TYPE_PERSONAL) {

            List<SmsUser> userList = smsUserMapper.selectBatchIds(planReq.getRangeIdList());
            if (userList == null || userList.isEmpty()) {
                return CommonResult.failed(CommonCodeEnum.USER_NOT_EXIST);
            }
            userIdList = planReq.getRangeIdList();
        }else {
            return CommonResult.failed(CommonCodeEnum.FAIL);
        }
        Set<String> userIdSet = new HashSet<>(userIdList);
        userIdList = new ArrayList<>(userIdSet);
        //创建资产自查计划
        SmsAssetSelfInspectionPlan plan = new SmsAssetSelfInspectionPlan();
        BeanUtils.copyProperties(planReq, plan);
        plan.setPlanName(planReq.getPlanName());
        plan.setPlanRangeType(planReq.getPlanRangeType());
        plan.setRangeIdList(JSON.toJSONString(planReq.getRangeIdList()));
        plan.setBgTime(planReq.getBgTime());
        plan.setEndTime(planReq.getEndTime());
        plan.setCreateUserId(userId);
        selfInspectionPlanMapper.insert(plan);
        String planId = plan.getId();
        if (isNullOrEmpty(planId)) {
            return CommonResult.failed(CommonCodeEnum.FAIL);
        }
        for (String userIdStr : userIdList) {
            //创建资产自查计划和用户关系表
            SmsAssetSelfInspection assetsSelfInspection = new SmsAssetSelfInspection();
            assetsSelfInspection.setPlanId(planId);
            assetsSelfInspection.setUserId(userIdStr);
            smsAssetSelfInspectionMapper.insert(assetsSelfInspection);
            String selfInspectionId = assetsSelfInspection.getId();
            if (isNullOrEmpty(selfInspectionId)) {
                return CommonResult.failed(CommonCodeEnum.FAIL);
            }
            //创建自查用户和资产详情表
            List<SmsAssetFixedStorage> fixedStorageList = smsAssetFixedStorageMapper.selectList(new LambdaQueryWrapper<SmsAssetFixedStorage>()
                    .eq(SmsAssetFixedStorage::getAssetOwner, userIdStr)
                    .ne(SmsAssetFixedStorage::getAssetStatus,ASSET_STATUS_OUT));
            if (fixedStorageList == null || fixedStorageList.isEmpty()) {
                assetsSelfInspection.setIsComplete(COMPLETED_TYPE_YES);
                assetsSelfInspection.setCompleteTime(new Date());
                smsAssetSelfInspectionMapper.updateById(assetsSelfInspection);
            }else {
                for (SmsAssetFixedStorage smsAssetFixedStorage : fixedStorageList) {
                    SmsAssetSelfInspectionDetail assetsSelfInspectionDetail = new SmsAssetSelfInspectionDetail();
                    assetsSelfInspectionDetail.setSelfInspectionId(selfInspectionId);
                    assetsSelfInspectionDetail.setPlanId(planId);
                    assetsSelfInspectionDetail.setAssetStatus(ASSET_STATUS_UNKNOWN);
                    assetsSelfInspectionDetail.setAssetId(smsAssetFixedStorage.getId());
                    assetsSelfInspectionDetail.setUserId(userIdStr);
                    smsAssetSelfInspectionDetailMapper.insert(assetsSelfInspectionDetail);
                }

            }
        }
        //消息通知
        newTipsUtil.addNewTips(TipsTypeEnum.TIPS_TYPE_ENUM_MESSAGE,
                userId,
                RangeTypeEnum.RANGE_TYPE_ENUM_PERSON,
                userIdList,
                CopyTypeEnum.COPY_TYPE_ENUM_NONE,
                null,
                AppTypeEnum.APP_TYPE_ENUM_ASSET_FIXED_CHECK,
                planId,
                null,
                TipsRecordStatusEnum.TIPS_RECORD_STATUS_ENUM_MESSAGE,
                null,
                null,
                null,
                null,
                null);
        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult updatePlan(SmsAssetSelfInspectionPlanReq planReq) {
        if (isNullOrEmpty(planReq.getId(),planReq.getPlanName(), planReq.getBgTime(), planReq.getEndTime())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        if (planReq.getBgTime().compareTo(planReq.getEndTime()) > 0) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_TIME_ILLEGALITY);
        }

        //创建资产自查计划
        SmsAssetSelfInspectionPlan plan = selfInspectionPlanMapper.selectById(planReq.getId());
        if (isNullOrEmpty(plan)) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_PLAN_NOT_EXIST);
        }

        BeanUtils.copyProperties(planReq, plan);
        plan.setPlanName(planReq.getPlanName());

        plan.setBgTime(planReq.getBgTime());
        plan.setEndTime(planReq.getEndTime());
        plan.setIsUse(planReq.getIsUse());
        plan.setIsOpenScan(planReq.getIsOpenScan());
        selfInspectionPlanMapper.updateById(plan);


        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult deletedPlan(SmsAssetSelfInspectionPlanReq planReq) {
        if (isNullOrEmpty(planReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.FAIL);
        }
        SmsAssetSelfInspectionPlan smsAssetSelfInspectionPlan = selfInspectionPlanMapper.selectById(planReq.getId());
        if (isNullOrEmpty(smsAssetSelfInspectionPlan)) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_PLAN_NOT_EXIST);
        }
        selfInspectionPlanMapper.deleteById(planReq.getId());
        smsAssetSelfInspectionMapper.delete(new LambdaQueryWrapper<SmsAssetSelfInspection>()
                .eq(SmsAssetSelfInspection::getPlanId, planReq.getId()));
        smsAssetSelfInspectionDetailMapper.delete(new LambdaQueryWrapper<SmsAssetSelfInspectionDetail>()
                .eq(SmsAssetSelfInspectionDetail::getPlanId, planReq.getId()));
        return CommonResult.success();
    }

    @Override
    public ResponseResult getPlanDetail(String id) {
        if (isNullOrEmpty(id)) {
            return CommonResult.failed(CommonCodeEnum.FAIL);
        }
        SmsAssetSelfInspectionPlan smsAssetSelfInspectionPlan = selfInspectionPlanMapper.selectById(id);
        if (isNullOrEmpty(smsAssetSelfInspectionPlan)) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_PLAN_NOT_EXIST);
        }
        SmsAssetSelfInspectionPlanResp resp = new SmsAssetSelfInspectionPlanResp();
        BeanUtils.copyProperties(smsAssetSelfInspectionPlan, resp);
        resp.setPlanId(smsAssetSelfInspectionPlan.getId());
        SmsSearchUserResp createUserInfo = new SmsSearchUserResp();
        List<SmsAssetSelfInspectionOrgResp> deparmentList = new ArrayList<>();
        List<SmsSearchUserResp> userList = new ArrayList<>();

        //范围
        String rangeIdList = smsAssetSelfInspectionPlan.getRangeIdList();
        if (smsAssetSelfInspectionPlan.getPlanRangeType() == PLAN_RANGE_TYPE_DEPARTMENT) {
            List<String> orgIdList = JSON.parseArray(rangeIdList, String.class);
            deparmentList = orgIdList.stream()
                    .map(orgId -> {
                        SmsAssetSelfInspectionOrgResp orgResp = new SmsAssetSelfInspectionOrgResp();
                        SmsOrgStructure smsOrgStructure = smsOrgStructureMapper.selectById(orgId);
                        if (!isNullOrEmpty(smsOrgStructure)) {
                            orgResp.setOrgName(smsOrgStructure.getOrgName());
                            orgResp.setLevel(smsOrgStructure.getLevel());
                            orgResp.setId(smsOrgStructure.getId());
                        }
                        return orgResp;
                    })
                    .collect(Collectors.toList());
        }else {
            List<String> userIdList = JSON.parseArray(rangeIdList, String.class);
            userList = userIdList.stream()
                    .map(userId -> {
                        SmsSearchUserResp searchUserResp = new SmsSearchUserResp();
                        SmsUser smsUser = smsUserMapper.selectById(userId);
                        if (!isNullOrEmpty(smsUser)) {
                            BeanUtils.copyProperties(smsUser, searchUserResp);
                        }
                        return searchUserResp;
                    }).collect(Collectors.toList());
        }
        //创建人
        SmsUser createUser = smsUserMapper.selectById(smsAssetSelfInspectionPlan.getCreateUserId());
        if (!isNullOrEmpty(createUser)) {
            BeanUtils.copyProperties(createUser, createUserInfo);
        }
        resp.setCreateUserInfo(createUserInfo);
        resp.setDeparmentList(deparmentList);
        resp.setUserList(userList);
        return CommonResult.success(resp);
    }

    @Override
    public ResponseResult getPlanList(Integer pageSize, Integer pageNum, String planName, Integer isUse) {
        Page<SmsAssetSelfInspectionPlan> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<SmsAssetSelfInspectionPlan> selfInspectionPlanLambdaQueryWrapper = new LambdaQueryWrapper<SmsAssetSelfInspectionPlan>()
                .orderByAsc(SmsAssetSelfInspectionPlan::getIsUse)
                .orderByDesc(SmsAssetSelfInspectionPlan::getCreateTime);
        if (!isNullOrEmpty(planName)) {
            selfInspectionPlanLambdaQueryWrapper.like(SmsAssetSelfInspectionPlan::getPlanName, planName);
        }
        if (!isNullOrEmpty(isUse)) {
            selfInspectionPlanLambdaQueryWrapper.eq(SmsAssetSelfInspectionPlan::getIsUse, isUse);
        }
        selfInspectionPlanMapper.selectPage(page, selfInspectionPlanLambdaQueryWrapper);
        List<SmsAssetSelfInspectionPlanResp> respList = page.getRecords()
                .stream()
                .map(smsAssetSelfInspectionPlan -> {
                    SmsAssetSelfInspectionPlanResp resp = new SmsAssetSelfInspectionPlanResp();
                    SmsSearchUserResp createUserInfo = new SmsSearchUserResp();
                    BeanUtils.copyProperties(smsAssetSelfInspectionPlan, resp);
                    resp.setPlanId(smsAssetSelfInspectionPlan.getId());
                    //创建人
                    SmsUser createUser = smsUserMapper.selectById(smsAssetSelfInspectionPlan.getCreateUserId());
                    if (!isNullOrEmpty(createUser)) {
                        BeanUtils.copyProperties(createUser, createUserInfo);
                    }
                    return resp;
                })
                .collect(Collectors.toList());
        return CommonResult.success(respList, (int) page.getTotal());
    }

    @Override
    public ResponseResult isOpen(SmsAssetSelfInspectionPlanReq planReq) {
        if (isNullOrEmpty(planReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.FAIL);
        }
        SmsAssetSelfInspectionPlan smsAssetSelfInspectionPlan = selfInspectionPlanMapper.selectById(planReq.getId());
        if (isNullOrEmpty(smsAssetSelfInspectionPlan)) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_PLAN_NOT_EXIST);
        }
        Integer isUse = smsAssetSelfInspectionPlan.getIsUse();
        if (isUse == IS_USE_YES) {
            smsAssetSelfInspectionPlan.setIsUse(IS_USE_NO);
        }else {
            smsAssetSelfInspectionPlan.setIsUse(IS_USE_YES);
        }
        selfInspectionPlanMapper.updateById(smsAssetSelfInspectionPlan);
        return CommonResult.success();
    }
}
